{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "lbFmQdsZs5eW"
   },
   "outputs": [],
   "source": [
    "# Import all the necessary files!\n",
    "import os\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras import layers\n",
    "from tensorflow.keras import Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "1xJZ5glPPCRz"
   },
   "outputs": [],
   "source": [
    "# Download the inception v3 weights\n",
    "!wget --no-check-certificate \\\n",
    "    https://storage.googleapis.com/mledu-datasets/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5 \\\n",
    "    -O /tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5\n",
    "\n",
    "# Import the inception model  \n",
    "from tensorflow.keras.applications.inception_v3 import InceptionV3\n",
    "\n",
    "# Create an instance of the inception model from the local pre-trained weights\n",
    "local_weights_file = '/tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'\n",
    "\n",
    "pre_trained_model = # Your Code Here\n",
    "\n",
    "pre_trained_model.load_weights(local_weights_file)\n",
    "\n",
    "# Make all the layers in the pre-trained model non-trainable\n",
    "for layer in pre_trained_model.layers:\n",
    "  # Your Code Here\n",
    "  \n",
    "# Print the model summary\n",
    "pre_trained_model.summary()\n",
    "\n",
    "# Expected Output is extremely large, but should end with:\n",
    "\n",
    "#batch_normalization_v1_281 (Bat (None, 3, 3, 192)    576         conv2d_281[0][0]                 \n",
    "#__________________________________________________________________________________________________\n",
    "#activation_273 (Activation)     (None, 3, 3, 320)    0           batch_normalization_v1_273[0][0] \n",
    "#__________________________________________________________________________________________________\n",
    "#mixed9_1 (Concatenate)          (None, 3, 3, 768)    0           activation_275[0][0]             \n",
    "#                                                                 activation_276[0][0]             \n",
    "#__________________________________________________________________________________________________\n",
    "#concatenate_5 (Concatenate)     (None, 3, 3, 768)    0           activation_279[0][0]             \n",
    "#                                                                 activation_280[0][0]             \n",
    "#__________________________________________________________________________________________________\n",
    "#activation_281 (Activation)     (None, 3, 3, 192)    0           batch_normalization_v1_281[0][0] \n",
    "#__________________________________________________________________________________________________\n",
    "#mixed10 (Concatenate)           (None, 3, 3, 2048)   0           activation_273[0][0]             \n",
    "#                                                                 mixed9_1[0][0]                   \n",
    "#                                                                 concatenate_5[0][0]              \n",
    "#                                                                 activation_281[0][0]             \n",
    "#==================================================================================================\n",
    "#Total params: 21,802,784\n",
    "#Trainable params: 0\n",
    "#Non-trainable params: 21,802,784"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "CFsUlwdfs_wg"
   },
   "outputs": [],
   "source": [
    "last_layer = pre_trained_model.get_layer(# Your Code Here)\n",
    "print('last layer output shape: ', last_layer.output_shape)\n",
    "last_output = # Your Code Here\n",
    "\n",
    "# Expected Output:\n",
    "# ('last layer output shape: ', (None, 7, 7, 768))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "-bsWZWp5oMq9"
   },
   "outputs": [],
   "source": [
    "# Define a Callback class that stops training once accuracy reaches 99.9%\n",
    "class myCallback(tf.keras.callbacks.Callback):\n",
    "  def on_epoch_end(self, epoch, logs={}):\n",
    "    if(logs.get('acc')>0.999):\n",
    "      print(\"\\nReached 99.9% accuracy so cancelling training!\")\n",
    "      self.model.stop_training = True\n",
    "\n",
    "      "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "BMXb913pbvFg"
   },
   "outputs": [],
   "source": [
    "from tensorflow.keras.optimizers import RMSprop\n",
    "\n",
    "# Flatten the output layer to 1 dimension\n",
    "x = layers.Flatten()(last_output)\n",
    "# Add a fully connected layer with 1,024 hidden units and ReLU activation\n",
    "x = layers.Dense(# Your Code Here)(x)\n",
    "# Add a dropout rate of 0.2\n",
    "x = layers.Dropout(# Your Code Here)(x)                  \n",
    "# Add a final sigmoid layer for classification\n",
    "x = layers.Dense  (# Your Code Here)(x)           \n",
    "\n",
    "model = Model( # Your Code Here, x) \n",
    "\n",
    "model.compile(optimizer = RMSprop(lr=0.0001), \n",
    "              loss = # Your Code Here, \n",
    "              metrics = # Your Code Here)\n",
    "\n",
    "model.summary()\n",
    "\n",
    "# Expected output will be large. Last few lines should be:\n",
    "\n",
    "# mixed7 (Concatenate)            (None, 7, 7, 768)    0           activation_248[0][0]             \n",
    "#                                                                  activation_251[0][0]             \n",
    "#                                                                  activation_256[0][0]             \n",
    "#                                                                  activation_257[0][0]             \n",
    "# __________________________________________________________________________________________________\n",
    "# flatten_4 (Flatten)             (None, 37632)        0           mixed7[0][0]                     \n",
    "# __________________________________________________________________________________________________\n",
    "# dense_8 (Dense)                 (None, 1024)         38536192    flatten_4[0][0]                  \n",
    "# __________________________________________________________________________________________________\n",
    "# dropout_4 (Dropout)             (None, 1024)         0           dense_8[0][0]                    \n",
    "# __________________________________________________________________________________________________\n",
    "# dense_9 (Dense)                 (None, 1)            1025        dropout_4[0][0]                  \n",
    "# ==================================================================================================\n",
    "# Total params: 47,512,481\n",
    "# Trainable params: 38,537,217\n",
    "# Non-trainable params: 8,975,264\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "HrnL_IQ8knWA"
   },
   "outputs": [],
   "source": [
    "# Get the Horse or Human dataset\n",
    "!wget --no-check-certificate https://storage.googleapis.com/laurencemoroney-blog.appspot.com/horse-or-human.zip -O /tmp/horse-or-human.zip\n",
    "\n",
    "# Get the Horse or Human Validation dataset\n",
    "!wget --no-check-certificate https://storage.googleapis.com/laurencemoroney-blog.appspot.com/validation-horse-or-human.zip -O /tmp/validation-horse-or-human.zip \n",
    "  \n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "import os\n",
    "import zipfile\n",
    "\n",
    "local_zip = '//tmp/horse-or-human.zip'\n",
    "zip_ref = zipfile.ZipFile(local_zip, 'r')\n",
    "zip_ref.extractall('/tmp/training')\n",
    "zip_ref.close()\n",
    "\n",
    "local_zip = '//tmp/validation-horse-or-human.zip'\n",
    "zip_ref = zipfile.ZipFile(local_zip, 'r')\n",
    "zip_ref.extractall('/tmp/validation')\n",
    "zip_ref.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "y9okX7_ovskI"
   },
   "outputs": [],
   "source": [
    "# Define our example directories and files\n",
    "train_dir = '/tmp/training'\n",
    "validation_dir = '/tmp/validation'\n",
    "\n",
    "train_horses_dir = # Your Code Here\n",
    "train_humans_dir = # Your Code Here\n",
    "validation_horses_dir = # Your Code Here\n",
    "validation_humans_dir = # Your Code Here\n",
    "\n",
    "train_horses_fnames = # Your Code Here\n",
    "train_humans_fnames = # Your Code Here\n",
    "validation_horses_fnames = # Your Code Here\n",
    "validation_humans_fnames = # Your Code Here\n",
    "\n",
    "print(# Your Code Here)\n",
    "print(# Your Code Here)\n",
    "print(# Your Code Here)\n",
    "print(# Your Code Here)\n",
    "\n",
    "# Expected Output:\n",
    "# 500\n",
    "# 527\n",
    "# 128\n",
    "# 128"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "O4s8HckqGlnb"
   },
   "outputs": [],
   "source": [
    "# Add our data-augmentation parameters to ImageDataGenerator\n",
    "train_datagen = ImageDataGenerator(# Your Code Here)\n",
    "\n",
    "# Note that the validation data should not be augmented!\n",
    "test_datagen = ImageDataGenerator(# Your Code Here )\n",
    "\n",
    "# Flow training images in batches of 20 using train_datagen generator\n",
    "train_generator = train_datagen.flow_from_directory(# Your Code Here)     \n",
    "\n",
    "# Flow validation images in batches of 20 using test_datagen generator\n",
    "validation_generator =  test_datagen.flow_from_directory( # Your Code Here)\n",
    "\n",
    "# Expected Output:\n",
    "# Found 1027 images belonging to 2 classes.\n",
    "# Found 256 images belonging to 2 classes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "Blhq2MAUeyGA"
   },
   "outputs": [],
   "source": [
    "# Run this and see how many epochs it should take before the callback\n",
    "# fires, and stops training at 99.9% accuracy\n",
    "# (It should take less than 100 epochs)\n",
    "\n",
    "callbacks = # Your Code Here\n",
    "history = model.fit_generator(# Your Code Here)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "C2Fp6Se9rKuL"
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "acc = history.history['acc']\n",
    "val_acc = history.history['val_acc']\n",
    "loss = history.history['loss']\n",
    "val_loss = history.history['val_loss']\n",
    "\n",
    "epochs = range(len(acc))\n",
    "\n",
    "plt.plot(epochs, acc, 'r', label='Training accuracy')\n",
    "plt.plot(epochs, val_acc, 'b', label='Validation accuracy')\n",
    "plt.title('Training and validation accuracy')\n",
    "plt.legend(loc=0)\n",
    "plt.figure()\n",
    "\n",
    "\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "name": "Exercise 7 - Question.ipynb",
   "provenance": [
    {
     "file_id": "1fRZWXUFO_p-N929XKh2hBTj_kOWuKJTS",
     "timestamp": 1553617840759
    },
    {
     "file_id": "https://github.com/lmoroney/dlaicourse/blob/master/Course%202%20-%20Part%206%20-%20Lesson%203%20-%20Notebook.ipynb",
     "timestamp": 1553613150204
    }
   ],
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
